package com.ltu.timkor6.gamesite.games.memory.server;

import com.ltu.timkor6.gamesite.games.memory.client.MemoryService;
import com.ltu.timkor6.gamesite.server.DataBaseConnection;
import com.ltu.timkor6.gamesite.server.GameSiteServiceImpl;
import com.ltu.timkor6.gamesite.shared.Result;

/**
 * Memory server
 * 
 * @author tim
 */

@SuppressWarnings("serial")
public class MemoryServiceImpl extends GameSiteServiceImpl implements MemoryService
{
	private Memory memory;
	private Result result;
	
	private int prevValue;
	private int prevRow;
	private int prevColumn;
	private int tries;
			
	public MemoryServiceImpl()
	{
		this.result = new Result();
		this.result.setGameTitle("Memory");
		
		this.memory = new Memory();
	}
	
	/**
	 * First time, starting game.
	 */
	public Boolean start(int size)
	{
		if(1 < size && size < 9 && size % 2 == 0)
		{
			this.memory.generate(size, size);
			
			this.result.setTurns(this.memory.getSize());
			
			this.tries = 0;
			this.prevValue = -1;
			this.prevRow = -1;
			this.prevColumn = -1;
			
			return true;
		}
		else
		{
			return false;
		}
	}
	
	/**
	 * First time, starting game.
	 */
	public int image(int row, int column)
	{
		int value = this.memory.getPosition(row, column);
		
		if(prevValue != -1)
		{
			this.tries++;
		}
		
		if(prevValue == value && (this.prevRow != row || this.prevColumn != column))
		{
			this.memory.getMatches().set(row, column, value);
			this.memory.getMatches().set(prevRow, prevColumn, value);
			
			this.prevValue = -1;
			this.prevRow = -1;
			this.prevColumn = -1;
		}
		else
		{
			this.prevValue = value;
			this.prevRow = row;
			this.prevColumn = column;
		}
		
		return value;
	}

	/**
	 * Check an answer and return given points.
	 */
	public Result finished()
	{
		if(this.memory.validate())
		{
			int points = givePoints();
			this.result.setPoints(points);
			
			if(this.userInfo != null)
			{
				new DataBaseConnection(this).addResult(result);
			}
			
			return result;
		}
		else
		{
			return null;
		}
	}
	
	/**
	 * Calculate points.
	 * @return
	 */
	private int givePoints()
	{
		int points = 0;
		
		// The bigger size the bigger score
		points += this.result.getTurns() * 5;
		
		// The more extra tries the lesser score
		points -= this.tries - this.result.getTurns();
		
		return points;
	}
}
